package com.yx.controller;

import com.alibaba.fastjson.JSON;
import com.yx.common.R;
import com.yx.constatns.AuthConstatns;
import com.yx.constatns.CarConstants;
import com.yx.constatns.RabbitMQConstatns;
import com.yx.constatns.RedisConstans;
import com.yx.feign.api.CarService;
import com.yx.feign.api.UserService;
import com.yx.utils.PasswordUtils;
import com.yx.vo.Customer;
import com.yx.vo.Sms;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Classname UserController
 * @Date 2021/07/13 19:08
 * @Author by yx
 * @Description TODO:
 */
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private CarService carService;

    @PostMapping("/checkUsername")
    @ResponseBody
    public Map<String, Object> checkUsername(String param) {
        //Ajax中会POST过来变量param和name。param是文本框的值，name是文本框的name属性。
        //返回数据data是json对象，{"info":"demo info","status":"y"}
        //info: 输出提示信息;
        //status: 返回提交数据的状态,是否提交成功。如可以用"y"表示提交成功，"n"表示提交失败
        Map<String, Object> map = new HashMap<>();
        //1.根据姓名查找用户
        Customer customer = userService.getUserByName(param);
        //2.判断
        if (customer == null) {
            //用户不存在--->可以注册
            map.put("status", "y");
            map.put("info", "用户名未被使用,可以注册");
        } else {
            //用户存在
            map.put("status", "n");
            map.put("info", "用户名存在,请重新选择用户名");
        }
        return map;
    }

    @GetMapping("/sendSms/{phone}")
    @ResponseBody
    public void sendSms(@PathVariable("phone") String phone) {
        log.debug(phone);

        //1.生成验证码
        /*
         * count:验证码个数;letters:是否含英文字母;number:是否含数字
         * 不可两项都选false
         * */
        String code = RandomStringUtils.random(6, false, true);
        //2.将验证码存储到redis数据库中,
        stringRedisTemplate.opsForValue().set(RedisConstans.AUTH_REGISTER_SMS_PRE + phone, code, 60, TimeUnit.SECONDS);
        //3.发送信息
        Sms sms = new Sms();
        sms.setCode(code);
        sms.setPhone(phone);
        String s = JSON.toJSONString(sms);
        rabbitTemplate.convertAndSend(RabbitMQConstatns.GOODS_EXCHANGE, "shop.sms.phone", s);
        log.debug("短信消息发送完成");
    }

    @PostMapping("/registerUser")
    @ResponseBody
    public R registerUser(Customer customer) {
        log.debug("{}", customer);
        //1.验证验证码
        String code = customer.getCode();
        //1.2.获取保存在redis中临时验证码
        String redisCode = stringRedisTemplate.opsForValue().get(RedisConstans.AUTH_REGISTER_SMS_PRE + customer.getPhone());
        //1.3比较
        if (redisCode == null) {
            return R.error("验证码已过期,请重新获取验证码");
        }
        if (!redisCode.equals(code)) {
            return R.error("验证码输入有误,请重新输入");
        }

        //2.密码加密
        customer.setPassword(PasswordUtils.haspw(customer.getPassword()));

        return R.write(userService.addUser(customer));
    }


    @PostMapping("/login")
    @ResponseBody
    public R login(String username, String password, HttpServletRequest request,
                   @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME,defaultValue = "") String annoId) {
        //1.验证用户是否存在
        Customer customer = userService.getUserByName(username);
        if (customer == null || !PasswordUtils.checkpw(password, customer.getPassword())) {
            //用户不存在,密码比对结果不一样,返回false 取反为true;或运算,一个为真便为真
            return R.error("用户名或密码不正确");
        }

        //3.认证信息存储到session中
        /*
         * springsession使用了自己的request与response,最终结果显示自己添加的httpsession变成了springsession
         * 故可以通过普通的session实现将session插入redis
         */
        request.getSession().setAttribute(AuthConstatns.AUTH_SESSION, customer);
//        String s = JSON.toJSONString(customer);
//        stringRedisTemplate.opsForValue().set(AuthConstatns.AUTH_REDIS+customer.getUsername(), s,1,TimeUnit.DAYS);

        //合并购物车 StringUtils.isEmpty()判断了是否为null与空字符串
        if (!StringUtils.isEmpty(annoId)){
            //匿名用户id存在才合并购物车
            carService.mergeCar(customer.getId(), annoId);
        }


        return R.success();
    }

    @GetMapping("/logout")
    public String logout(HttpSession session){
        //清除session
        session.invalidate();
        return "redirect:http://localhost/auth/login.html";
    }
}
